package com.hc.mybatis.generator.plugins;

import com.hc.mybatis.generator.plugins.utils.CommentTools;
import com.hc.mybatis.generator.plugins.utils.XmlElementGeneratorTools;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.List;

/**
 * @Description: 添加根据条件查询单条的方法
 * @author: hc
 * @version: v1.0
 * @create at: 2020/7/15 19:51
 * @reviewer:
 * @review at:
 * <p>
 * Revision history:
 * date             author      version     content
 * ------------------------------------------------------------
 * 2020/7/15           hc          v1.0        XXXX
 */
public class SelectOneByExamplePlugin extends PluginAdapter {

    public static final String METHOD_NAME = "selectOneByExample";

    public SelectOneByExamplePlugin() {
    }

    @Override
    public boolean validate(List<String> warnings) {
        if (StringUtility.stringHasValue(this.getContext().getTargetRuntime()) && !"MyBatis3".equalsIgnoreCase(this.getContext().getTargetRuntime())) {
            System.out.println("itfsw:插件" + this.getClass().getTypeName() + "要求运行targetRuntime必须为MyBatis3！");
            return false;
        } else {
            return true;
        }
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        Method method = new Method("selectOneByExample");
        FullyQualifiedJavaType returnType = introspectedTable.getRules().calculateAllFieldsClass();
        method.setReturnType(returnType);
        FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getExampleType());
        method.addParameter(new Parameter(type, "example"));
        CommentTools.addGeneralMethodComment(method, "根据条件查询单条数据");
        interfaze.addMethod(method);
        System.out.println("itfsw(查询单条数据插件):" + interfaze.getType().getShortName() + "增加SelectOneByExample方法。");
        return true;
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();
        XmlElement selectOneElement = new XmlElement("select");
        CommentTools.addComment(selectOneElement);
        selectOneElement.addAttribute(new Attribute("id", "selectOneByExample"));
        StringBuilder sb;
        XmlElement ifElement;
        if (introspectedTable.hasBLOBColumns()) {
            selectOneElement.addAttribute(new Attribute("resultMap", introspectedTable.getResultMapWithBLOBsId()));
            selectOneElement.addAttribute(new Attribute("parameterType", introspectedTable.getExampleType()));
            selectOneElement.addElement(new TextElement("select"));
            sb = new StringBuilder();
            if (StringUtility.stringHasValue(introspectedTable.getSelectByExampleQueryId())) {
                sb.append('\'');
                sb.append(introspectedTable.getSelectByExampleQueryId());
                sb.append("' as QUERYID,");
                selectOneElement.addElement(new TextElement(sb.toString()));
            }

            selectOneElement.addElement(XmlElementGeneratorTools.getBaseColumnListElement(introspectedTable));
            selectOneElement.addElement(new TextElement(","));
            selectOneElement.addElement(XmlElementGeneratorTools.getBlobColumnListElement(introspectedTable));
            sb.setLength(0);
            sb.append("from ");
            sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
            selectOneElement.addElement(new TextElement(sb.toString()));
            selectOneElement.addElement(XmlElementGeneratorTools.getExampleIncludeElement(introspectedTable));
            ifElement = new XmlElement("if");
            ifElement.addAttribute(new Attribute("test", "orderByClause != null"));
            ifElement.addElement(new TextElement("order by ${orderByClause}"));
            selectOneElement.addElement(ifElement);
            selectOneElement.addElement(new TextElement("limit 1"));
        } else {
            selectOneElement.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
            selectOneElement.addAttribute(new Attribute("parameterType", introspectedTable.getExampleType()));
            selectOneElement.addElement(new TextElement("select"));
            sb = new StringBuilder();
            if (StringUtility.stringHasValue(introspectedTable.getSelectByExampleQueryId())) {
                sb.append('\'');
                sb.append(introspectedTable.getSelectByExampleQueryId());
                sb.append("' as QUERYID,");
                selectOneElement.addElement(new TextElement(sb.toString()));
            }

            selectOneElement.addElement(XmlElementGeneratorTools.getBaseColumnListElement(introspectedTable));
            sb.setLength(0);
            sb.append("from ");
            sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
            selectOneElement.addElement(new TextElement(sb.toString()));
            selectOneElement.addElement(XmlElementGeneratorTools.getExampleIncludeElement(introspectedTable));
            ifElement = new XmlElement("if");
            ifElement.addAttribute(new Attribute("test", "orderByClause != null"));
            ifElement.addElement(new TextElement("order by ${orderByClause}"));
            selectOneElement.addElement(ifElement);
            selectOneElement.addElement(new TextElement("limit 1"));
        }

        document.getRootElement().addElement(selectOneElement);
        System.out.println("itfsw(查询单条数据插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加SelectOneByExample方法(" + (introspectedTable.hasBLOBColumns() ? "有" : "无") + "Blob类型))。");
        return true;
    }

}